package test.solrcloud;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Test;

import com.alibaba.fastjson.JSON;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.druid.DruidPlugin;

public class Facet extends BaseSolrCloudTest {
	
	@Test
	public void test1() {
		SolrQuery query = new SolrQuery();
		query.setQuery("*:*");
		query.addFacetField("channel_id");
		try {
			QueryResponse qr = client.query("test1", query);
			System.out.println(JSON.toJSONString(qr.getResponse().asMap(Integer.MAX_VALUE), true));
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	static String url = "jdbc:mysql://192.168.5.33/goods?characterEncoding=UTF-8";
	static String username = "licai";
	static String password = "123456";
	static int pageSize = 1000;
	
	@Test
	public void test2() {
		DruidPlugin dp = new DruidPlugin(url, username, password);
		ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
		arp.setDevMode(true);
		arp.setShowSql(true);
		dp.start();
		arp.start();
		
		int page = 1;
		while(true) {
			System.out.println("执行到第" + page + "页");
			String sql = "select * from goods limit ";
			int start = ((page++) - 1) * pageSize;
			sql += start + "," + pageSize;
			List<Record> list = Db.find(sql);
			if(list.size()<pageSize) break;
			List<SolrInputDocument> docs = new ArrayList<>();
			list.forEach(new Consumer<Record>() {
				@Override
				public void accept(Record t) {
					Integer id = t.getInt("id");
					Integer evaluateCount = t.getInt("evaluate_count");
					
					String category = t.getStr("category");
					String brand = t.getStr("brand");
					
					String name = t.getStr("name");
					String company = t.getStr("company");
					
					Double JdPrice = t.getBigDecimal("jd_price").doubleValue();
					Double MarketPrice = t.getBigDecimal("market_price").doubleValue();
					
					Date ctime = t.getDate("ctime");
					
					SolrInputDocument doc = new SolrInputDocument();
					doc.addField("id", id);
					doc.addField("evaluateCount", evaluateCount);
					doc.addField("category", category);
					doc.addField("brand", brand);
					doc.addField("name", name);
					doc.addField("company", company);
					doc.addField("JdPrice", JdPrice);
					doc.addField("MarketPrice", MarketPrice);
					doc.addField("ctime", ctime);
					
					docs.add(doc);
				}
			});
			try {
				client.add("test2", docs);
				client.commit("test2");
			} catch (SolrServerException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	@Test
	public void test3() {
		SolrQuery query = new SolrQuery();
//		query.setQuery("JdPrice:[* TO 1000]");
		query.setQuery("*:*");
//		query.addFacetQuery("JdPrice:[* TO 100]");
		/**
		 * 从多个维度进行统计
		 */
//		query.addFacetField("category", "brand");
//		query.addFacetField("category");
		/**
		 * 二维统计，一个字符串，逗号分开
		 */
//		query.addFacetPivotField("category,brand");
//		Date start = new JDateTime("2015-11-18", "YYYY-MM-DD").convertToDate();
//		Date end = new JDateTime("2015-11-25", "YYYY-MM-DD").convertToDate();
		
		/**
		 * 区间统计
		 * gap:
		 * /HOUR
		      ... Round to the start of the current hour
		   /DAY
		      ... Round to the start of the current day
		   +2YEARS
		      ... Exactly two years in the future from now
		   -1DAY
		      ... Exactly 1 day prior to now
		   /DAY+6MONTHS+3DAYS
		      ... 6 months and 3 days in the future from the start of
		          the current day
		   +6MONTHS+3DAYS/DAY
		      ... 6 months and 3 days in the future from now, rounded
		          down to nearest day
		 */
//		query.addDateRangeFacet("ctime", start, end, "+1DAY");
//		query.addNumericRangeFacet("JdPrice", 1, 1000, 100);
		
		/**
		 * 更加灵活的统计
		 */
//		query.addIntervalFacets("JdPrice", new String[]{"{!key=1-100}[1,100]", "{!key=101-200}[101,200]"});
		
		/**
		 * 各项统计结果
		 *  min=0.0,
	        max=131700.0,
	        count=176000,
	        missing=0,
	        sum=1.9820193E7,
	        sumOfSquares=3.33156230347E11,
	        mean=112.61473295454546,
	        stddev=1371.2263606707916
		 * 
		 */
//		query.addGetFieldStatistics("JdPrice", "evaluateCount");
//		query.addFacetField("category");
		/**
		 * stats + facet
		 * 两个必须同时设置
		 */
//		query.addGetFieldStatistics("JdPrice");
//		query.addStatsFieldFacets("JdPrice", "category");
		
		/**
		 * 直接给参数赋值的方式，更灵活
		 */
//		query.add("facet", "true");
//		query.add("facet.field", "category");
		/**
		 * 
			facet.field
				Identifies a field to be treated as a facet.
			facet.prefix
				Limits the terms used for faceting to those that begin with the specified prefix.
			facet.contains
				Limits the terms used for faceting to those that contain the specified substring.
			facet.contains.ignoreCase
				If facet.contains is used, ignore case when searching for the specified substring.
			facet.sort
				Controls how faceted results are sorted.
			facet.limit
				Controls how many constraints should be returned for each facet.
			facet.offset
				Specifies an offset into the facet results at which to begin displaying facets.
			facet.mincount
				Specifies the minimum counts required for a facet field to be included in the response.
			facet.missing
				Controls whether Solr should compute a count of all matching results which
			have no value for the field, in addition to the term-based constraints of a facet
			field.
			
			facet.method
				Selects the algorithm or method Solr should use when faceting a field.
			facet.enum.cache.minDF
				(Advanced) Specifies the minimum document frequency (the number of
			documents matching a term) for which the filterCache should be used
			when determining the constraint count for that term.
			
			facet.overrequest.count
				(Advanced) A number of documents, beyond the effective facet.limit 
			to request from each shard in a distributed search
			
			facet.overrequest.ratio
				(Advanced) A multiplier of the effective facet.limit 
			to request from each shard in a distributed search
			
			facet.threads
			(Advanced) Controls parallel execution of field faceting
		 * 
		 */
//		query.add("facet.mincount", "10000");
		/**
		 * sort:index(按照值排),count(默认)
		 */
//		query.add("facet.sort", "index");
		
		/**
		 * pivot整合stats
		 */
		query.add("stats", "true");
		query.add("stats.field", "{!tag=JdPrice min=true max=true mean=true}JdPrice");
//		query.add("stats.field", "{!tag=evaluateCount min=true,max=true,mean=true}evaluateCOunt");
		
		query.add("facet", "true");
		query.add("facet.pivot", "{!stats=JdPrice}category");
		query.add("facet.limit", "2");
		
		
		query.setRows(0);
		try {
			QueryResponse qr = client.query("test2", query);
			System.out.println(qr);
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}
